2. Content
2.1 Question 1
2.1.1 Read Data
## get currency dataset online.
## http://stackoverflow.com/questions/24219694/get-symbols-quantmod-ohlc-currency-data
#'@ getFX('USD/JPY', from = '2014-01-01', to = '2017-01-20')
## getFX() doesn't shows Op, Hi, Lo, Cl price but only price. Therefore no idea to place bets.
#'@ USDJPY <- getSymbols('JPY=X', src = 'yahoo', from = '2014-01-01',
#'@ to = '2017-01-20', auto.assign = FALSE)
#'@ names(USDJPY) <- str_replace_all(names(USDJPY), 'JPY=X', 'USDJPY')
#'@ USDJPY <- xts(USDJPY[, -1], order.by = USDJPY$Date)
#'@ saveRDS(USDJPY, './data/USDJPY.rds')
USDJPY <- read_rds(path = './data/USDJPY.rds')
mbase <- USDJPY
## dateID
dateID <- index(mbase)
dateID0 <- ymd('2015-01-01')
dateID <- dateID[dateID > dateID0]
## load fund files which is from chunk `r simStaking-woutLog`.
fundOPHI <- readRDS('./data/fundOPHI.rds')
fundHIHI <- readRDS('./data/fundHIHI.rds')
fundMNHI <- readRDS('./data/fundMNHI.rds')
fundLOHI <- readRDS('./data/fundLOHI.rds')
fundCLHI <- readRDS('./data/fundCLHI.rds')
fundOPMN <- readRDS('./data/fundOPMN.rds')
fundHIMN <- readRDS('./data/fundHIMN.rds')
fundMNMN <- readRDS('./data/fundMNMN.rds')
fundLOMN <- readRDS('./data/fundLOMN.rds')
fundCLMN <- readRDS('./data/fundCLMN.rds')
fundOPLO <- readRDS('./data/fundOPLO.rds')
fundHILO <- readRDS('./data/fundHILO.rds')
fundMNLO <- readRDS('./data/fundMNLO.rds')
fundLOLO <- readRDS('./data/fundLOLO.rds')
fundCLLO <- readRDS('./data/fundCLLO.rds')
fundOPCL <- readRDS('./data/fundOPCL.rds')
fundHICL <- readRDS('./data/fundHICL.rds')
fundMNCL <- readRDS('./data/fundMNCL.rds')
fundLOCL <- readRDS('./data/fundLOCL.rds')
fundCLCL <- readRDS('./data/fundCLCL.rds')
## Placed orders - Fund size without log
fundList <- list(fundOPHI = fundOPHI, fundHIHI = fundHIHI, fundMNHI = fundMNHI, fundLOHI = fundLOHI, fundCLHI = fundCLHI,
fundOPMN = fundOPMN, fundHIMN = fundHIMN, fundMNMN = fundMNMN, fundLOMN = fundLOMN, fundCLMN = fundCLMN,
fundOPLO = fundOPLO, fundHILO = fundHILO, fundMNLO = fundMNLO, fundLOLO = fundLOLO, fundCLLO = fundCLLO,
fundOPCL = fundOPCL, fundHICL = fundHICL, fundMNCL = fundMNCL, fundLOCL = fundLOCL, fundCLCL = fundCLCL)
2.1.2 Statistical Modelling
2.1.2.1 ARIMA vs ETS
Remarks : Here I try to predict the sell/buy price and also settled price. However just noticed the question asking about prediction of the variance2 The profit is made based on the range of variance Hi-Lo price but not the accuracy of the highest, lowest or closing price. based on mean price. I can also use the focasted highest and forecasted lowest price for variance prediction as well. However I will conduct another study and answer for the variance with Garch models.
Below are some articles with regards exponential smoothing.
- Recent Advances in Robust Statistics: Theory and Applications
- Error, trend, seasonality - ets and its forecast model friends
- A study of outliers in the exponential smoothing approach to forecasting
- 8.10 ARIMA vs ETS
- Introduction to ARIMA : nonseasonal models
It is a common myth that ARIMA models are more general than exponential smoothing. While linear exponential smoothing models are all special cases of ARIMA models, the non-linear exponential smoothing models have no equivalent ARIMA counterparts. There are also many ARIMA models that have no exponential smoothing counterparts. In particular, every ETS model3 forecast::ets() : Usually a three-character string identifying method using the framework terminology of Hyndman et al. (2002) and Hyndman et al. (2008). The first letter denotes the error type (“A”, “M” or “Z”); the second letter denotes the trend type (“N”,“A”,“M” or “Z”); and the third letter denotes the season type (“N”,“A”,“M” or “Z”). In all cases, “N”=none, “A”=additive, “M”=multiplicative and “Z”=automatically selected. So, for example, “ANN” is simple exponential smoothing with additive errors, “MAM” is multiplicative Holt-Winters’ method with multiplicative errors, and so on. It is also possible for the model to be of class “ets”, and equal to the output from a previous call to ets. In this case, the same model is fitted to y without re-estimating any smoothing parameters. See also the use.initial.values argument. is non-stationary, while ARIMA models can be stationary.
The ETS models with seasonality or non-damped trend or both have two unit roots (i.e., they need two levels of differencing to make them stationary). All other ETS models have one unit root (they need one level of differencing to make them stationary).
The following table gives some equivalence relationships for the two classes of models.
| ETS model | ARIMA model | Parameters |
|---|---|---|
| \(ETS(A, N, N)\) | \(ARIMA(0, 1, 1)\) | \(θ_{1} = α − 1\) |
| \(ETS(A, A, N)\) | \(ARIMA(0, 2, 2)\) | \(θ_{1} = α + β − 2\) |
| \(θ_{2} = 1 − α\) | ||
| \(ETS(A, A_{d}, N)\) | \(ARIMA(1, 1, 2)\) | \(ϕ_{1} = ϕ\) |
| \(θ_{1} = α + ϕβ − 1 − ϕ\) | ||
| \(θ_{2} = (1 − α)ϕ\) | ||
| \(ETS(A, N, A)\) | \(ARIMA(0, 0, m)(0, 1, 0)_{m}\) | |
| \(ETS(A, A, A)\) | \(ARIMA(0, 1, m+1)(0, 1, 0)_{m}\) | |
| \(ETS(A, A_{d}, A)\) | \(ARIMA(1, 0, m+1)(0, 1, 0)_{m}\) |
For the seasonal models, there are a large number of restrictions on the ARIMA parameters.
Kindly refer to 8.10 ARIMA vs ETS for further details.
## Modelling ETS focasting data.
fitETS.op <- suppressAll(simETS(USDJPY, .prCat = 'Op')) #will take a minute
fitETS.hi <- suppressAll(simETS(USDJPY, .prCat = 'Hi')) #will take a minute
fitETS.mn <- suppressAll(simETS(USDJPY, .prCat = 'Mn')) #will take a minute
fitETS.lo <- suppressAll(simETS(USDJPY, .prCat = 'Lo')) #will take a minute
fitETS.cl <- suppressAll(simETS(USDJPY, .prCat = 'Cl')) #will take a minute
Application of MCMC
Need to refer to MCMC since I am using exponential smoothing models…
## Need to test and read through the MCMCregress... after few months later (when free)... Start working as a servant at Bah-Kut-Teh restorant tommorrow 01-Mar-2017.
## Here I test the accuracy of forecasting of ets ZZZ model 1.
## Test the models
## opened price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitETS.op))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitETS.op)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.4353 -0.4004 -0.0269 0.3998 3.3978
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.180332 0.490019 0.368 0.713
## USDJPY.Close 0.998722 0.004256 234.666 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7286 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9904, Adjusted R-squared: 0.9904
## F-statistic: 5.507e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitETS.op))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.1808 0.489606 4.896e-03 4.896e-03
## USDJPY.Close 0.9987 0.004257 4.257e-05 4.257e-05
## sigma2 0.5330 0.033014 3.301e-04 3.301e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.7795 -0.1487 0.1848 0.5094 1.1441
## USDJPY.Close 0.9904 0.9959 0.9987 1.0016 1.0070
## sigma2 0.4716 0.5100 0.5317 0.5549 0.6009
## highest price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitETS.hi))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitETS.hi)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3422 -0.3298 -0.0987 0.2166 3.2868
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.140616 0.379253 3.008 0.00276 **
## USDJPY.Close 0.993982 0.003294 301.765 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5639 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9942, Adjusted R-squared: 0.9942
## F-statistic: 9.106e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitETS.hi))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 1.1410 0.378933 3.789e-03 3.789e-03
## USDJPY.Close 0.9940 0.003295 3.295e-05 3.295e-05
## sigma2 0.3193 0.019776 1.978e-04 1.978e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) 0.3978 0.8860 1.1441 1.3953 1.8865
## USDJPY.Close 0.9875 0.9918 0.9939 0.9962 1.0004
## sigma2 0.2825 0.3055 0.3185 0.3324 0.3599
## mean price fit data (mean price of daily highest and lowest price)
summary(lm(Point.Forecast~ USDJPY.Close, data = fitETS.mn))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitETS.mn)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.55047 -0.26416 -0.00996 0.26743 1.81654
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.106616 0.326718 0.326 0.744
## USDJPY.Close 0.999098 0.002838 352.091 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4858 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9957, Adjusted R-squared: 0.9957
## F-statistic: 1.24e+05 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitETS.mn))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.1069 0.326443 3.264e-03 3.264e-03
## USDJPY.Close 0.9991 0.002838 2.838e-05 2.838e-05
## sigma2 0.2369 0.014676 1.468e-04 1.468e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.5333 -0.1127 0.1096 0.3260 0.7492
## USDJPY.Close 0.9935 0.9972 0.9991 1.0010 1.0046
## sigma2 0.2096 0.2267 0.2364 0.2467 0.2671
## lowest price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitETS.lo))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitETS.lo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.1318 -0.2450 0.0860 0.3331 1.4818
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.3885 0.3684 -3.769 0.000182 ***
## USDJPY.Close 1.0083 0.0032 315.094 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5478 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9947, Adjusted R-squared: 0.9947
## F-statistic: 9.928e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitETS.lo))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) -1.3881 0.368114 3.681e-03 3.681e-03
## USDJPY.Close 1.0082 0.003201 3.201e-05 3.201e-05
## sigma2 0.3013 0.018663 1.866e-04 1.866e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -2.1101 -1.6358 -1.3851 -1.1410 -0.6638
## USDJPY.Close 1.0020 1.0061 1.0082 1.0104 1.0145
## sigma2 0.2666 0.2883 0.3006 0.3137 0.3397
## closed price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitETS.cl))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitETS.cl)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.4339 -0.4026 -0.0249 0.3998 3.4032
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.17826 0.49050 0.363 0.716
## USDJPY.Close 0.99873 0.00426 234.437 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7293 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9904, Adjusted R-squared: 0.9904
## F-statistic: 5.496e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitETS.cl))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.1787 0.490086 4.901e-03 4.901e-03
## USDJPY.Close 0.9987 0.004261 4.261e-05 4.261e-05
## sigma2 0.5340 0.033079 3.308e-04 3.308e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.7825 -0.1511 0.1827 0.5077 1.1430
## USDJPY.Close 0.9904 0.9959 0.9987 1.0016 1.0071
## sigma2 0.4725 0.5110 0.5327 0.5559 0.6021
Mean Squared Error
fcdata <- do.call(cbind, list(USDJPY.FPOP.Open = fitETS.op$Point.Forecast,
USDJPY.FPHI.High = fitETS.hi$Point.Forecast,
USDJPY.FPMN.Mean = fitETS.mn$Point.Forecast,
USDJPY.FPLO.Low = fitETS.lo$Point.Forecast,
USDJPY.FPCL.Close = fitETS.cl$Point.Forecast,
USDJPY.Open = fitETS.op$USDJPY.Open,
USDJPY.High = fitETS.op$USDJPY.High,
USDJPY.Low = fitETS.op$USDJPY.Low,
USDJPY.Close = fitETS.op$USDJPY.Close))
fcdata <- na.omit(fcdata)
names(fcdata) <- c('USDJPY.FPOP.Open', 'USDJPY.FPHI.High', 'USDJPY.FPMN.Mean',
'USDJPY.FPLO.Low', 'USDJPY.FPCL.Close', 'USDJPY.Open',
'USDJPY.High', 'USDJPY.Low', 'USDJPY.Close')
## Mean Squared Error : comparison of accuracy
paste('Open = ', mean((fcdata$USDJPY.FPOP.Open - fcdata$USDJPY.Open)^2))
## [1] "Open = 0.524327826450961"
paste('High = ', mean((fcdata$USDJPY.FPHI.High - fcdata$USDJPY.High)^2))
## [1] "High = 0.458369038353778"
paste('Mean = ', mean((fcdata$USDJPY.FPMN.Mean - (fcdata$USDJPY.High + fcdata$USDJPY.Low)/2)^2))
## [1] "Mean = 0.414913471187317"
paste('Low = ', mean((fcdata$USDJPY.FPLO.Low - fcdata$USDJPY.Low)^2))
## [1] "Low = 0.623518861674962"
paste('Close = ', mean((fcdata$USDJPY.FPCL.Close - fcdata$USDJPY.Close)^2))
## [1] "Close = 0.531069865476858"
2.1.2.2 Garch vs EWMA
Now we look at Garch model, Figlewski (2004)4 Paper 19th applied few models and also using different length of data for comparison. Now I use daily Hi-Lo and 365 days data in order to predict the next market price. The author applid Garch on SAP200, 10-years-bond and 20-years-bond and concludes that the Garch model is better than eGarch but implied volatility model better than Garch and eGarch, and the monthly Hi-Lo data is better accurate than daily Hi-Lo for long term investment.
\[h_{t} = {\omega} + \sum_{i=1}^q{{\alpha}_{i} {\epsilon}_{t-i}^2} + \sum_{j=1}^p{{\gamma}_{j} h_{t-j}}\ \dots equation\ 2.1.2.2.1\]
- Volatility Forecasting Using GARCH(1,1)
- Regime Switching System Using Volatility Forecast
- Normalized Price Spread Strategy
- Volatility Autocorrelation in Different Markets
- Basic Introduction to GARCH and EGARCH (part 1)
- Basic Introduction to GARCH and EGARCH (part 2)
- Basic Introduction to GARCH and EGARCH (Part 3)5 Using this EGARCH model, we can epect a better estimate the volatility for assets returns due to how the EGARCH counteracts the limitations on the classic GARCH model.Here is the final part of the series of posts on the volatility modelling where I will briefly talk about one of the many variant of the GARCH model: the exponential GARCH (abbreviated EGARCH). I chose this variant because it improves the GARCH model and better model some market mechanics. In the GARCH post, I didn’t mention any of the limitation of the model as I kept them for today’s post. First of all, the GARCH model assume that only the magnitude of unanticipated excess returns determines \(\sigma^2_t\). Intuitively, we can question this assumption; I, for one, would argue that not only the magnitude but also the direction of the returns affects volatility.
-
Volatility Analysis
- AGARCH
- APARCH
- Asy. MEM
- Asy. Power MEM
- CDS-GARCH
- CDS-GARCH-DYN
- EGARCH
- GARCH
- GAS-GARCH Student T
- GJR-GARCH
- MEM
- Spline-GARCH
Correlation Analysis
- EWMA Covariance
- GARCH-DCC
- GARCH-DECO
- GJR-DCC
Systemic Risk Analysis
- Domestic MES
- Dynamic MES
- Dynamic MES with Simulation
Long Run Value at Risk
- Long Term GJR-GARCH Forecast
Liquidity Analysis
- Asymmetric ILLIQ
- Historical ILLIQ
Fixed Income Analysis
- Extensions of the GARCH Model6 Comparison among the GARCH, TGARCH (Threshold GARCH) and EGARCH (Exponential GARCH) models.
- How to fit ARMA+GARCH Model In R?
- A short introduction to the rugarch package
- A practical introduction to garch modeling
- ARCH-GARCH Example with R
- Financial Econometrics Practical Practical 6: Univariate Volatility Modelling
- Multivariate GARCH(1,1) in R
- R - Modelling Multivariate GARCH (rugarch and ccgarch)
- Introduction to some R package
- Introduction to the ruGarch package
- The rmgarch models: Background and properties. - R Project
Firstly we use rugarch and then rmgarch to compare the result.
## http://www.unstarched.net/r-examples/rugarch/a-short-introduction-to-the-rugarch-package/
ugarchspec()
##
## *---------------------------------*
## * GARCH Model Spec *
## *---------------------------------*
##
## Conditional Variance Dynamics
## ------------------------------------
## GARCH Model : sGARCH(1,1)
## Variance Targeting : FALSE
##
## Conditional Mean Dynamics
## ------------------------------------
## Mean Model : ARFIMA(1,0,1)
## Include Mean : TRUE
## GARCH-in-Mean : FALSE
##
## Conditional Distribution
## ------------------------------------
## Distribution : norm
## Includes Skew : FALSE
## Includes Shape : FALSE
## Includes Lambda : FALSE
## This defines a basic ARMA(1,1)-GARCH(1,1) model, though there are many more options to choose from ranging from the type of GARCH model, the ARFIMAX-arch-in-mean specification and conditional distribution. In fact, and considering only the (1,1) order for the GARCH and ARMA models, there are 13440 possible combinations of models and model options to choose from:
## possible Garch models.
nrow(expand.grid(GARCH = 1:14, VEX = 0:1, VT = 0:1, Mean = 0:1, ARCHM = 0:2, ARFIMA = 0:1, MEX = 0:1, DISTR = 1:10))
## [1] 13440
spec = ugarchspec(variance.model = list(model = 'eGARCH', garchOrder = c(2, 1)), distribution = 'std')
There will be 13440 possible combination Garch models. Here I tried to filter few among them.
Now we try to build some Garch models to get the best fit.
## Multiple Garch models inside `rugarch` package.
.variance.model <- c('sGARCH', 'fGARCH', 'eGARCH', 'gjrGARCH', 'apARCH', 'iGARCH', 'sGARCH', 'realGARCH')
.garchOrder <- expand.grid(1:5, 1:5, KEEP.OUT.ATTRS = FALSE) %>% mutate(PP = paste(Var1, Var2)) %>% .$PP %>% str_split(' ')
.solver <- c('nlminb', 'solnp', 'lbfgs', 'gosolnp', 'nloptr', 'hybrid')
.sub.fGarch <- c('GARCH', 'TGARCH', 'AVGARCH', 'NGARCH', 'NAGARCH', 'APARCH', 'GJRGARCH', 'ALLGARCH')
.dist.model <- c('norm', 'snorm', 'std', 'sstd', 'ged', 'sged', 'nig', 'ghyp', 'jsu')
## =========================== Eval = FALSE ===========================
## http://www.unstarched.net/2014/01/02/the-realized-garch-model/
## https://eranraviv.com/volatility-forecast-evaluation-in-r/
## https://eranraviv.com/univariate-volatility-forecast-evaluation/
garch.m <- suppressAll(llply(dateID, function(dt) {
llply(.variance.model, function(vm) {
llply(.garchOrder, function(gO) {
llply(.solver, function(sv) {
llply(.dist.model, function(dst) {
if(vm == 'fGARCH'){
llply(.sub.fGarch, function(sub.vm) {
spec = ugarchspec(variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])), submodel = sub.vm), distribution.model = dst)
smp = USDJPY
dtr = last(index(smp[index(smp) < dt]))
smp = smp[paste0(dtr %m-% years(1), '/', dtr)]
frd = as.numeric(difftime(dt, dtr), units = 'days')
fit = ugarchfit(spec, smp, solver = sv)
if(frd > 1) dt = seq(dt - days(frd), dt, by = 'days')[-1]
gfocast = ugarchforecast(fit, n.ahead = frd)
data.frame(Date = dt, fSeries = attributes(gfocast)[1]$forecast$seriesFor[frd]) %>% tbl_df
}, .progress = 'text')
} else {
spec = ugarchspec(variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])), submodel = NULL), distribution.model = dst)
smp = USDJPY
dtr = last(index(smp[index(smp) < dt]))
smp = smp[paste0(dtr %m-% years(1), '/', dtr)]
frd = as.numeric(difftime(dt, dtr), units = 'days')
fit = ugarchfit(spec, smp, solver = sv)
if(frd > 1) dt = seq(dt - days(frd), dt, by = 'days')[-1]
gfocast = ugarchforecast(fit, n.ahead = frd)
data.frame(Date = dt, fSeries = attributes(gfocast)[1]$forecast$seriesFor[frd]) %>% tbl_df
}
}, .progress = 'text')
}, .progress = 'text')
}, .progress = 'text')
}, .progress = 'text')
}, .progress = 'text'))
## Forecast simulation on the Garch models.
llply(.variance.models, function(vm) {
llply(.garchOrders, function(gO) {
llply(.solvers, function(sv) {
llply(.dist.models, function(dst) {
if(vm == 'fGARCH'){
llply(.sub.fGarchs, function(sub.vm) {
spec = ugarchspec(
variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])),
submodel = sub.vm, external.regressors = NULL,
variance.targeting = FALSE),
mean.model = list(armaOrder = c(1, 1), include.mean = TRUE,
archm = FALSE, archpow = 1, arfima = FALSE,
external.regressors = NULL, archex = FALSE),
distribution.model = dst, start.pars = list(), fixed.pars = list())
fit = ugarchfit(spec, mbase, solver = sv)
}, .progress = .progress)
} else {
spec = ugarchspec(
variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])),
submodel = NULL, external.regressors = NULL,
variance.targeting = FALSE),
mean.model = list(armaOrder = c(1, 1), include.mean = TRUE,
archm = FALSE, archpow = 1, arfima = FALSE,
external.regressors = NULL, archex = FALSE),
distribution.model = dst, start.pars = list(), fixed.pars = list())
fit = ugarchfit(spec, mbase, solver = sv)
}
}, .progress = .progress)
}, .progress = .progress)
}, .progress = .progress)
}, .progress = .progress)
test <- suppressAll(llply(dateID, function(dt) {
spec = ugarchspec(variance.model = list(model = .variance.model[2], garchOrder = c(as.numeric(.garchOrder[[1]][1]), as.numeric(.garchOrder[[1]][2])), submodel = .sub.fGarch[7]), distribution.model = .dist.model[1])
smp = mbase
dtr = last(index(mbase[index(mbase) < dateID[1]]))
smp = smp[paste0(dtr %m-% years(1), '/', dtr)]
frd = as.numeric(difftime(dt, dtr), units = 'days')
fit = ugarchfit(spec, smp, solver = .solver[1])
if(frd > 1) dt = seq(dt - days(frd), dt, by = 'days')[-1]
data.frame(Date = dt, ugarchforecast(fit, n.ahead = frd)) ## need to modify this row
}))
garch.m <- llply(.variance.model, function(vm) {
llply(.garchOrder, function(gO) {
llply(.solver, function(sv) {
llply(.dist.model, function(dst) {
if(vm == 'fGARCH'){
llply(.sub.fGarch, function(sub.vm) {
spec = ugarchspec(variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])), submodel = sub.vm), distribution.model = dst)
fit = ugarchfit(spec, mbase, solver = sv)
}, .progress = 'text')
} else {
spec = ugarchspec(variance.model = list(model = vm, garchOrder = c(as.numeric(gO[1]), as.numeric(gO[2])), submodel = NULL), distribution.model = dst)
fit = ugarchfit(spec, mbase, solver = sv)
}
}, .progress = 'text')
}, .progress = 'text')
}, .progress = 'text')
}, .progress = 'text')
## Tested model - parameters
mbase = USDJPY; .solver = 'solnp'; .prCat = 'Mn'; .baseDate = ymd('2015-01-01');
.parallel = FALSE; .progress = 'text';
.variance.model = list(model = 'sGARCH', garchOrder = c(1, 1),
submodel = NULL, external.regressors = NULL,
variance.targeting = FALSE);
.mean.model = list(armaOrder = c(1, 1), include.mean = TRUE, archm = FALSE,
archpow = 1, arfima = FALSE, external.regressors = NULL,
archex = FALSE);
.dist.model = 'norm'; start.pars = list(); fixed.pars = list()
## Modelling Garch focasting data.
fitGM.op <- suppressAll(simGarch(USDJPY, .prCat = 'Op')) #will take a minute
fitGM.hi <- suppressAll(simGarch(USDJPY, .prCat = 'Hi')) #will take a minute
fitGM.mn <- suppressAll(simGarch(USDJPY, .prCat = 'Mn')) #will take a minute
fitGM.lo <- suppressAll(simGarch(USDJPY, .prCat = 'Lo')) #will take a minute
fitGM.cl <- suppressAll(simGarch(USDJPY, .prCat = 'Cl')) #will take a minute
Application of MCMC
Need to refer to MCMC since I am using Garch models…
## Need to test and read through the MCMCregress... after few months later (when free)... Start working as a servant at Bah-Kut-Teh restorant tommorrow 01-Mar-2017.
## Here I test the accuracy of forecasting of ets ZZZ model 1.
## Test the models
## opened price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitGM.op))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitGM.op)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3916 -0.4120 -0.0287 0.4042 3.4518
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.484484 0.489840 0.989 0.323
## USDJPY.Close 0.995918 0.004254 234.093 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7284 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9904, Adjusted R-squared: 0.9903
## F-statistic: 5.48e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitGM.op))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.4850 0.489426 4.894e-03 4.894e-03
## USDJPY.Close 0.9959 0.004256 4.256e-05 4.256e-05
## sigma2 0.5326 0.032990 3.299e-04 3.299e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.4750 0.1556 0.4889 0.8135 1.4479
## USDJPY.Close 0.9876 0.9931 0.9959 0.9988 1.0042
## sigma2 0.4712 0.5096 0.5313 0.5545 0.6005
## highest price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitGM.hi))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitGM.hi)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3354 -0.3257 -0.0915 0.2335 3.3945
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.323767 0.378529 3.497 0.00051 ***
## USDJPY.Close 0.992355 0.003288 301.847 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5628 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9942, Adjusted R-squared: 0.9942
## F-statistic: 9.111e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitGM.hi))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 1.3241 0.378210 3.782e-03 3.782e-03
## USDJPY.Close 0.9924 0.003288 3.288e-05 3.288e-05
## sigma2 0.3180 0.019700 1.970e-04 1.970e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) 0.5823 1.0696 1.3272 1.5780 2.0683
## USDJPY.Close 0.9859 0.9902 0.9923 0.9946 0.9988
## sigma2 0.2814 0.3043 0.3173 0.3311 0.3586
## mean price fit data (mean price of daily highest and lowest price)
summary(lm(Point.Forecast~ USDJPY.Close, data = fitGM.mn))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitGM.mn)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.84741 -0.27127 -0.01094 0.25695 1.54721
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.063814 0.319695 0.2 0.842
## USDJPY.Close 0.999350 0.002777 359.9 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4754 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9959, Adjusted R-squared: 0.9959
## F-statistic: 1.295e+05 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitGM.mn))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.06412 0.319426 3.194e-03 3.194e-03
## USDJPY.Close 0.99935 0.002777 2.777e-05 2.777e-05
## sigma2 0.22687 0.014052 1.405e-04 1.405e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.5624 -0.1508 0.06671 0.2785 0.6926
## USDJPY.Close 0.9939 0.9975 0.99932 1.0012 1.0048
## sigma2 0.2007 0.2171 0.22631 0.2362 0.2558
## lowest price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitGM.lo))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitGM.lo)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.1529 -0.2299 0.1041 0.3135 1.5187
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.051234 0.369685 -2.844 0.00463 **
## USDJPY.Close 1.005105 0.003211 313.040 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.5497 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9946, Adjusted R-squared: 0.9946
## F-statistic: 9.799e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitGM.lo))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) -1.0509 0.369373 3.694e-03 3.694e-03
## USDJPY.Close 1.0051 0.003212 3.212e-05 3.212e-05
## sigma2 0.3034 0.018791 1.879e-04 1.879e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -1.7754 -1.2994 -1.0479 -0.8029 -0.3241
## USDJPY.Close 0.9988 1.0030 1.0051 1.0073 1.0114
## sigma2 0.2684 0.2903 0.3026 0.3158 0.3420
## closed price fit data
summary(lm(Point.Forecast~ USDJPY.Close, data = fitGM.cl))
##
## Call:
## lm(formula = Point.Forecast ~ USDJPY.Close, data = fitGM.cl)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.3833 -0.4024 -0.0282 0.4100 3.4593
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.515358 0.490139 1.051 0.294
## USDJPY.Close 0.995611 0.004257 233.878 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7288 on 533 degrees of freedom
## (216 observations deleted due to missingness)
## Multiple R-squared: 0.9903, Adjusted R-squared: 0.9903
## F-statistic: 5.47e+04 on 1 and 533 DF, p-value: < 2.2e-16
summary(MCMCregress(Point.Forecast~ USDJPY.Close, data = fitGM.cl))
##
## Iterations = 1001:11000
## Thinning interval = 1
## Number of chains = 1
## Sample size per chain = 10000
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## (Intercept) 0.5158 0.489725 4.897e-03 4.897e-03
## USDJPY.Close 0.9956 0.004258 4.258e-05 4.258e-05
## sigma2 0.5333 0.033030 3.303e-04 3.303e-04
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## (Intercept) -0.4447 0.1863 0.5198 0.8445 1.4794
## USDJPY.Close 0.9873 0.9928 0.9956 0.9985 1.0039
## sigma2 0.4718 0.5103 0.5320 0.5551 0.6012
Mean Squared Error
fcdataGM <- do.call(cbind, list(USDJPY.FPOP.Open = fitGM.op$Point.Forecast,
USDJPY.FPHI.High = fitGM.hi$Point.Forecast,
USDJPY.FPMN.Mean = fitGM.mn$Point.Forecast,
USDJPY.FPLO.Low = fitGM.lo$Point.Forecast,
USDJPY.FPCL.Close = fitGM.cl$Point.Forecast,
USDJPY.Open = fitGM.op$USDJPY.Open,
USDJPY.High = fitGM.op$USDJPY.High,
USDJPY.Low = fitGM.op$USDJPY.Low,
USDJPY.Close = fitGM.op$USDJPY.Close))
fcdataGM <- na.omit(fcdataGM)
names(fcdataGM) <- c('USDJPY.FPOP.Open', 'USDJPY.FPHI.High', 'USDJPY.FPMN.Mean',
'USDJPY.FPLO.Low', 'USDJPY.FPCL.Close', 'USDJPY.Open',
'USDJPY.High', 'USDJPY.Low', 'USDJPY.Close')
## Mean Squared Error : comparison of accuracy
paste('Open = ', mean((fcdataGM$USDJPY.FPOP.Open - fcdataGM$USDJPY.Open)^2))
## [1] "Open = 0.523983739988711"
paste('High = ', mean((fcdataGM$USDJPY.FPHI.High - fcdataGM$USDJPY.High)^2))
## [1] "High = 0.451413382991846"
paste('Mean = ', mean((fcdataGM$USDJPY.FPMN.Mean - (fcdataGM$USDJPY.High + fcdataGM$USDJPY.Low)/2)^2))
## [1] "Mean = 0.395942093707128"
paste('Low = ', mean((fcdataGM$USDJPY.FPLO.Low - fcdataGM$USDJPY.Low)^2))
## [1] "Low = 0.624684562103111"
paste('Close = ', mean((fcdataGM$USDJPY.FPCL.Close - fcdataGM$USDJPY.Close)^2))
## [1] "Close = 0.530350467165783"
2.1.2.3 MCMC vs Bayesian Time Series
## Sorry ARIMA, but I’m Going Bayesian
## http://multithreaded.stitchfix.com/blog/2016/04/21/forget-arima/
#'@ library('bsts')
## Need to testing and compare the models (packages : MCMCPack and bsts).
2.1.2.4 MIDAS
2.1.3 Data Visualization
Plot graph.
2.1.3.1 ARIMA vs ETS
## Plot the models
## opened price fit data
autoplot(forecast(ets(fitETS.op$Point.Forecast), h = 4), facets = TRUE) + geom_forecast(color = '#ffcccc', show.legend = FALSE) + labs(x = 'Day', y = 'Forex Price', "Forecasts from ETS model")
#'@ ggplot(data = pd, aes(x = date, y = observed)) + geom_line(color = 'red') + geom_line(aes(y = fitted), color = "blue") + geom_line(aes(y = forecast)) + geom_ribbon(aes(ymin = lo95, ymax = hi95), alpha = .25) + scale_x_date(name = "Time in Decades") + scale_y_continuous(name = "GDP per capita (current US$)") + theme(axis.text.x = element_text(size = 10), legend.justification=c(0,1), legend.position=c(0,1)) + ggtitle("Arima(0,1,1) Fit and Forecast of GDP per capita for Brazil (1960-2013)") + scale_color_manual(values = c("Blue", "Red"), breaks = c("Fitted", "Data", "Forecast")) + ggsave((filename = "gdp_forecast_ggplot.pdf"), width=330, height=180, units=c("mm"), dpi = 300, limitsize = TRUE)
## highest price fit data
autoplot(forecast(ets(fitETS.hi$Point.Forecast), h = 4), facets = TRUE) + geom_forecast(color = '#FFCCCC', show.legend = FALSE) + labs(x = 'Day', y = 'Forex Price', 'Forecasts from ETS model')
## mean price fit data (mean price of daily highest and lowest price)
autoplot(forecast(ets(fitETS.mn$Point.Forecast), h = 4), facets = TRUE) + geom_forecast(color = '#FFCCCC', show.legend = FALSE) + labs(x = 'Day', y = 'Forex Price', 'Forecasts from ETS model')
## lowest price fit data
autoplot(forecast(ets(fitETS.lo$Point.Forecast), h = 4), facets = TRUE) + geom_forecast(color = '#FFCCCC', show.legend = FALSE) + labs(x = 'Day', y = 'Forex Price', 'Forecasts from ETS model')
## opened price fit data
autoplot(forecast(ets(fitETS.cl$Point.Forecast), h = 4), facets = TRUE) + geom_forecast(color = '#FFCCCC', show.legend = FALSE) + labs(x = 'Day', y = 'Forex Price', 'Forecasts from ETS model')
source('./function/plotChart2.R', local = TRUE)
suppressAll(rm(fitETS.op, fitETS.hi, fitETS.mn, fitETS.lo, fitETS.cl))
plotChart2(fcdata, initialName = 'FP', chart.type = 'FP', graph.title = 'USDJPY')
2.1.3.2 Garch vs EWMA
2.1.3.3 MCMC vs Bayesian Time Series
2.1.3.4 MIDAS
2.1.4 Staking Model
2.1.4.1 ARIMA vs ETS
Staking function. Here I apply Kelly criterion as the betting strategy. I don’t pretend to know the order of price flutuation flow from the Hi-Lo price range, therefore I just using Closing price for settlement while the staking price restricted within the variance (Hi-Lo) to made the transaction stand. The settled price can only be closing price unless staking price is opening price which sellable within the Hi-Lo range.
Due to we cannot know the forecasted sell/buy price and also forecasted closing price which is coming first solely from Hi-Lo data, therefore the Profit&Loss will slidely different (sell/buy price = forecasted sell/buy price).
- Forecasted profit = edge based on forecasted sell/buy price - forecasted settled price.
- If the forecasted sell/buy price doesn’t exist within the Hi-Lo price, then the transaction is not stand.
- If the forecasted settled price does not exist within the Hi-Lo price, then the settled price will be the real closing price.
Kindly refer to Quintuitive ARMA Models for Trading to know how to determine PULL or CALL with ARMA models7 The author compare the ROI between Buy-and-Hold with GARCH model..
Here I set an application of leverage while it is very risky (the variance of ROI is very high) as we can know from later comparison.
2.1.4.2 Garch vs EWMA
2.1.4.3 MCMC vs Bayesian Time Series
2.1.4.4 MIDAS
2.1.5 Return of Investment
2.1.5.1 ARIMA vs ETS
Profit and Loss of default ZZZ ets models.
##============================ EVAL = FALSE ================================
##
## Leveraged model 4
##
## Placed orders - Fund size with log and revert back exp() after calculation.
fundOPHI <- simStakes(mbase, .prCat = 'Op', .setPrice = 'Hi', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundHIHI <- simStakes(mbase, .prCat = 'Hi', .setPrice = 'Hi', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundMNHI <- simStakes(mbase, .prCat = 'Mn', .setPrice = 'Hi', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundLOHI <- simStakes(mbase, .prCat = 'Lo', .setPrice = 'Hi', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundCLHI <- simStakes(mbase, .prCat = 'Cl', .setPrice = 'Hi', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundOPMN <- simStakes(mbase, .prCat = 'Op', .setPrice = 'Mn', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundHIMN <- simStakes(mbase, .prCat = 'Hi', .setPrice = 'Mn', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundMNMN <- simStakes(mbase, .prCat = 'Mn', .setPrice = 'Mn', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundLOMN <- simStakes(mbase, .prCat = 'Lo', .setPrice = 'Mn', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundCLMN <- simStakes(mbase, .prCat = 'Cl', .setPrice = 'Mn', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundOPLO <- simStakes(mbase, .prCat = 'Op', .setPrice = 'Lo', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundHILO <- simStakes(mbase, .prCat = 'Hi', .setPrice = 'Lo', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundMNLO <- simStakes(mbase, .prCat = 'Mn', .setPrice = 'Lo', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundLOLO <- simStakes(mbase, .prCat = 'Lo', .setPrice = 'Lo', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundCLLO <- simStakes(mbase, .prCat = 'Cl', .setPrice = 'Lo', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundOPCL <- simStakes(mbase, .prCat = 'Op', .setPrice = 'Cl', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundHICL <- simStakes(mbase, .prCat = 'Hi', .setPrice = 'Cl', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundMNCL <- simStakes(mbase, .prCat = 'Mn', .setPrice = 'Cl', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundLOCL <- simStakes(mbase, .prCat = 'Lo', .setPrice = 'Cl', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
fundCLCL <- simStakes(mbase, .prCat = 'Cl', .setPrice = 'Cl', .initialFundSize = log(1000),
.fundLeverageLog = TRUE)
## Placed orders - Fund size with log
#'@ fundList <- list(fundOPHI = fundOPHI, fundHIHI = fundHIHI, fundMNHI = fundMNHI, fundLOHI = fundLOHI, fundCLHI = fundCLHI,
#'@ fundOPMN = fundOPMN, fundHIMN = fundHIMN, fundMNMN = fundMNMN, fundLOMN = fundLOMN, fundCLMN = fundCLMN,
#'@ fundOPLO = fundOPLO, fundHILO = fundHILO, fundMNLO = fundMNLO, fundLOLO = fundLOLO, fundCLLO = fundCLLO,
#'@ fundOPCL = fundOPCL, fundHICL = fundHICL, fundMNCL = fundMNCL, fundLOCL = fundLOCL, fundCLCL = fundCLCL)
#'@
#'@ ldply(fundList, function(x) { x %>% mutate(StartDate = first(Date), LatestDate = last(Date), InitFund = first(BR), LatestFund = last(Bal), Profit = sum(Profit), RR = LatestFund/InitFund) %>% dplyr::select(StartDate, LatestDate, InitFund, LatestFund, Profit, RR) %>% unique }) %>% tbl_df
# ldply(fundList, function(x) { x %>% mutate(StartDate = first(Date), LatestDate = last(Date), InitFund = first(BR), LatestFund = last(Bal), Profit = sum(Profit), RR = LatestFund/InitFund) %>% dplyr::select(StartDate, LatestDate, InitFund, LatestFund, Profit, RR) %>% unique }) %>% tbl_df
# A tibble: 20 × 7
# .id StartDate LatestDate InitFund LatestFund Profit RR
# <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
# 1 fundOPHI 2015-01-02 2017-01-20 6.907755 7.010568e+24 6.130503e+03 1.014884e+24
# 2 fundHIHI 2015-01-02 2017-01-20 6.907755 2.718282e+00 5.350000e+02 3.935116e-01
# 3 fundMNHI 2015-01-02 2017-01-20 6.907755 2.711146e+00 5.344836e+02 3.924786e-01
# 4 fundLOHI 2015-01-02 2017-01-20 6.907755 2.718282e+00 6.039260e+09 3.935116e-01
# 5 fundCLHI 2015-01-02 2017-01-20 6.907755 5.090087e+21 5.261994e+03 7.368655e+20
# 6 fundOPMN 2015-01-02 2017-01-20 6.907755 2.198185e+01 9.372727e+02 3.182199e+00
# 7 fundHIMN 2015-01-02 2017-01-20 6.907755 2.718282e+00 2.362245e+03 3.935116e-01
# 8 fundMNMN 2015-01-02 2017-01-20 6.907755 2.718282e+00 5.350000e+02 3.935116e-01
# 9 fundLOMN 2015-01-02 2017-01-20 6.907755 2.718282e+00 3.257372e+04 3.935116e-01
# 10 fundCLMN 2015-01-02 2017-01-20 6.907755 1.441047e+01 9.002950e+02 2.086129e+00
# 11 fundOPLO 2015-01-02 2017-01-20 6.907755 1.161927e+00 2.719083e+03 1.682061e-01
# 12 fundHILO 2015-01-02 2017-01-20 6.907755 2.718282e+00 1.202578e+06 3.935116e-01
# 13 fundMNLO 2015-01-02 2017-01-20 6.907755 1.043987e+00 2.932865e+03 1.511326e-01
# 14 fundLOLO 2015-01-02 2017-01-20 6.907755 2.718282e+00 5.350000e+02 3.935116e-01
# 15 fundCLLO 2015-01-02 2017-01-20 6.907755 1.166220e+00 1.999664e+03 1.688276e-01
# 16 fundOPCL 2015-01-02 2017-01-20 6.907755 2.861825e+00 5.414756e+02 4.142917e-01
# 17 fundHICL 2015-01-02 2017-01-20 6.907755 2.718282e+00 1.639176e+05 3.935116e-01
# 18 fundMNCL 2015-01-02 2017-01-20 6.907755 7.550813e+00 7.034814e+02 1.093092e+00
# 19 fundLOCL 2015-01-02 2017-01-20 6.907755 2.718282e+00 1.359407e+08 3.935116e-01
# 20 fundCLCL 2015-01-02 2017-01-20 6.907755 2.718282e+00 5.350000e+02 3.935116e-01
From above table summary we can know that model 1 without any leverage will be growth with a stable pace where LoHi and LoHi generates highest return rates. fundLOHI indicates investment fund buy at LOwest price and sell at HIghest price and vice verse.
#4 fundLOHI 2015-01-02 2017-01-20 1000 816.63808 1816.638 1.816638
#12 fundHILO 2015-01-02 2017-01-20 1000 649.35074 1649.351 1.649351
2.1.5.2 Garch vs EWMA
2.1.5.3 MCMC vs Bayesian Time Series
2.1.5.4 MIDAS
2.1.6 Return of Investment Optimization
2.1.6.1 ARIMA vs ETS
Now we apply the bootstrap onto the simulation of the forecasting.
## set all models provided by ets function.
ets.m1 <- c('A', 'M', 'Z')
ets.m2 <- c('N', 'A', 'M', 'Z')
ets.m3 <- c('N', 'A', 'M', 'Z')
ets.m <- do.call(paste0, expand.grid(ets.m1, ets.m2, ets.m3))
rm(ets.m1, ets.m2, ets.m3)
pp <- expand.grid(c('Op', 'Hi', 'Mn', 'Lo', 'Cl'), c('Op', 'Hi', 'Mn', 'Lo', 'Cl')) %>% mutate(PP = paste(Var1, Var2)) %>% .$PP %>% str_split(' ')
In order to trace the errors, here I check the source codes of the function but also test the coding as you can know via Error : Forbidden model combination #554. Here I only take 22 models among 48 models.
## load the pre-run and saved models.
## Profit and Loss of multi-ets models. 22 models.
## Due to the file name contains 'MNM' is not found in directory but appear in dir(), Here I force to omit it...
#' @> sapply(ets.m, function(x) {
#' @ dir('data', pattern = x) %>% length
#' @ }, USE.NAMES = TRUE) %>% .[. > 0]
#ANN MNN ZNN AAN MAN ZAN MMN ZMN AZN MZN ZZN MNM ANZ MNZ ZNZ AAZ MAZ ZAZ MMZ ZMZ AZZ MZZ ZZZ
# 25 25 25 25 25 25 25 25 25 25 25 1 25 25 25 25 25 25 25 25 25 25 25
nms <- sapply(ets.m, function(x) {
dir('data', pattern = x) %>% length
}, USE.NAMES = TRUE) %>% .[. == 25] %>% names #here I use only [. == 25].
#'@ nms <- sapply(ets.m, function(x) {
#'@ dir('data', pattern = x) %>% length
#'@ }, USE.NAMES = TRUE) %>% .[. > 0] %>% names #here original [. > 0].
fls <- sapply(nms, function(x) {
sapply(pp, function(y) {
dir('data', pattern = paste0(x, '.', y[1], y[2]))
})
})
## From 22 ets models with 25 hilo, opcl, mnmn, opop etc different price data. There will be 550 models.
fundList <- llply(fls, function(dt) {
cbind(Model = str_replace_all(dt, '.rds', ''),
readRDS(file = paste0('./data/', dt))) %>% tbl_df
})
names(fundList) <- sapply(fundList, function(x) xts::first(x$Model))
## Summary of ROI
ets.tbl <- ldply(fundList, function(x) { x %>% mutate(StartDate = xts::first(Date), LatestDate = last(Date), InitFund = xts::first(BR), LatestFund = last(Bal), Profit = sum(Profit), RR = LatestFund/InitFund) %>% dplyr::select(StartDate, LatestDate, InitFund, LatestFund, Profit, RR) %>% unique }) %>% tbl_df
#'@ ets.tbl %>% dplyr::filter(RR == max(RR))
# A tibble: 2 x 7
# .id StartDate LatestDate InitFund LatestFund Profit RR
# <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
#1 AZN.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
#2 AZZ.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
llply(c('LoHi', 'HiLo'), function(ppr) {
ets.tbl %>% dplyr::filter(.id %in% grep(ppr, ets.tbl$.id, value = TRUE)) %>% dplyr::filter(RR == max(RR))
})
## [[1]]
## # A tibble: 2 x 7
## .id StartDate LatestDate InitFund LatestFund Profit RR
## <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
## 1 AZN.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
## 2 AZZ.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
##
## [[2]]
## # A tibble: 2 x 7
## .id StartDate LatestDate InitFund LatestFund Profit RR
## <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
## 1 AZN.HiLo 2015-01-02 2017-01-20 1000 1666.752 666.7518 1.666752
## 2 AZZ.HiLo 2015-01-02 2017-01-20 1000 1666.752 666.7518 1.666752
#[[1]]
# A tibble: 2 x 7
# .id StartDate LatestDate InitFund LatestFund Profit RR
# <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
#1 AZN.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
#2 AZZ.LoHi 2015-01-02 2017-01-20 1000 1834.058 834.058 1.834058
#
#[[2]]
# A tibble: 2 x 7
# .id StartDate LatestDate InitFund LatestFund Profit RR
# <chr> <date> <date> <dbl> <dbl> <dbl> <dbl>
#1 AZN.HiLo 2015-01-02 2017-01-20 1000 1666.752 666.7518 1.666752
#2 AZZ.HiLo 2015-01-02 2017-01-20 1000 1666.752 666.7518 1.666752
From above table, we find the ets model AZN and AZZ generates highest return compare to rest of 21 ets models.
Figlewski (2004) applied few models and also using different length of data for comparison. Now I use daily Hi-Lo and 365 days data in order to predict the next market price. Since I only predict 2 years investment therefore a further research works on the data sizing and longer prediction terms need (for example: 1 month, 3 months, 6 months data to predict coming price, 2ndly comparison of the ROI from 7 years or upper).
Variance/Volatility Analsis
Hereby, I try to place bets on the variance which is requested by the assessment.
##
## From 22 ets models with 25 hilo, opcl, mnmn, opop etc different price data. There will be 550 models.
fundList <- llply(fls[grep('HiLo|LoHi', fls)], function(dt) {
cbind(Model = str_replace_all(dt, '.rds', ''),
readRDS(file = paste0('./data/', dt))) %>% tbl_df
})
names(fundList) <- sapply(fundList, function(x) xts::first(x$Model))
## Focast the variance and convert to probability.
varHL <- fundList[grep('HiLo|LoHi', names(fundList))]
ntm <- c(names((varHL)[names(varHL) %in% c('Date', 'USDJPY.High', 'USDJPY.Low', 'USDJPY.Close')]), names((varHL)[!names(varHL) %in% c('Date', 'USDJPY.High', 'USDJPY.Low', 'USDJPY.Close')])) %>% str_replace('.HiLo|.LoHi', '') %>% unique %>% sort
varHL1 <- suppressMessages(llply(varHL, function(dtx) {
mm = tbl_df(dtx) %>% dplyr::select(Date, USDJPY.High, USDJPY.Low, USDJPY.Close, Point.Forecast)
names(mm)[5] = as.character(dtx$Model[1])
names(mm) = str_replace_all(names(mm), 'HiLo', 'High')
names(mm) = str_replace_all(names(mm), 'LoHi', 'Low')
mm
}) %>% join_all) %>% tbl_df
varHL2 <- suppressMessages(llply(ntm, function(nm) {
mld = varHL1[grep(nm, names(varHL1))]
mld[,3] = abs(mld[,1] - mld[,2])
names(mld)[3] = paste0(nm, '.Rng')
mld = mld[colSums(!is.na(mld)) > 0]
data.frame(varHL1[c('Date', 'USDJPY.High', 'USDJPY.Low', 'USDJPY.Close')], USDJPY.Rng = abs(varHL1$USDJPY.High - varHL1$USDJPY.Low), mld) %>% tbl_df
}) %>% unique %>% join_all %>% tbl_df)
## Application of MASS::mvrnorm() or mvtnorm::rmvnorm() ##nope
#'@ varHL2 <- xts(varHL2[, -1], as.Date(varHL2$Date))
## Betting strategy 1 - Normal range betting
varB1 <- varHL2[,c('Date', names(varHL2)[str_detect(names(varHL2), '.Rng')])]
varB1 <- suppressMessages(llply(ntm, function(nm) {
dtx = bind_cols(varB1[c('USDJPY.Rng')], varB1[grep(nm, names(varB1))]) %>% mutate_if(is.numeric, funs(ifelse(USDJPY.Rng >= ., ., -100)))
dtx2 = dtx[, 2] %>% mutate_if(is.numeric, funs(ifelse(. >= 0, 100, -100)))
dtx3 = dtx2 %>% mutate_if(is.numeric, funs(cumsum(.) + 1000))
dtx4 = dtx2 %>% mutate_if(is.numeric, funs(lag(1000 + cumsum(.))))
dtx4[1,1] = 1000
dtx5 = bind_cols(varB1['Date'], dtx4, dtx2, dtx3)
names(dtx5) = names(dtx5) %>% str_replace_all('Rng2', 'Bal')
names(dtx5) = names(dtx5) %>% str_replace_all('Rng1', 'PL')
names(dtx5) = names(dtx5) %>% str_replace_all('Rng', 'BR')
dtx5
}) %>% join_all %>% tbl_df)
## shows the last 6 balance (ROI)
tail(data.frame(varB1['Date'], varB1[grep('Bal', names(varB1))])) %>% kable(width = 'auto')
| Date | AAN.Bal | AAZ.Bal | ANN.Bal | ANZ.Bal | AZN.Bal | AZZ.Bal | MAN.Bal | MAZ.Bal | MMN.Bal | MMZ.Bal | MNN.Bal | MNZ.Bal | MZN.Bal | MZZ.Bal | ZAN.Bal | ZAZ.Bal | ZMN.Bal | ZMZ.Bal | ZNN.Bal | ZNZ.Bal | ZZN.Bal | ZZZ.Bal | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 530 | 2017-01-13 | 2800 | 2800 | -200 | -200 | -200 | -200 | 3600 | 3600 | 3000 | 3000 | 200 | 200 | 2000 | 2000 | 3200 | 3200 | 3000 | 3000 | -200 | -200 | 1200 | 1200 |
| 531 | 2017-01-16 | 2700 | 2700 | -300 | -300 | -300 | -300 | 3500 | 3500 | 2900 | 2900 | 100 | 100 | 1900 | 1900 | 3100 | 3100 | 2900 | 2900 | -300 | -300 | 1100 | 1100 |
| 532 | 2017-01-17 | 2800 | 2800 | -200 | -200 | -200 | -200 | 3600 | 3600 | 3000 | 3000 | 200 | 200 | 2000 | 2000 | 3200 | 3200 | 3000 | 3000 | -200 | -200 | 1200 | 1200 |
| 533 | 2017-01-18 | 2700 | 2700 | -300 | -300 | -300 | -300 | 3500 | 3500 | 2900 | 2900 | 100 | 100 | 1900 | 1900 | 3100 | 3100 | 2900 | 2900 | -300 | -300 | 1100 | 1100 |
| 534 | 2017-01-19 | 2800 | 2800 | -200 | -200 | -200 | -200 | 3600 | 3600 | 3000 | 3000 | 200 | 200 | 2000 | 2000 | 3200 | 3200 | 3000 | 3000 | -200 | -200 | 1200 | 1200 |
| 535 | 2017-01-20 | 2700 | 2700 | -300 | -300 | -300 | -300 | 3500 | 3500 | 2900 | 2900 | 100 | 100 | 1900 | 1900 | 3100 | 3100 | 2900 | 2900 | -300 | -300 | 1100 | 1100 |
From above coding and below graph, we can know my first staking method8 The variance range is solely based on forecasted figures irrespect the volatility of real time effect, only made settlement after closed market. After that use the daily Hi-Lo variance compare to initial forecasted variance. Even though there has no such highest price nor lowest price will not affect the predicted transaction. which is NOT EXCEED the daily Hi-Lo range will generates profit or ruined depends on the statistical models.
The 2nd staking method is based on real-time volativity which is the transaction will only stand if the highest or lowest price happenned within hte variance, same with the initial Kelly staking model. The closing Price will be Highest or Lowest price if one among the price doesn’t exist within the range of variance.
It doesn’t work since the closed price MUST be between highest and lowest price. Here I stop it and set as eval = FALSE for display purpose but not execute
2.1.6.2 Garch vs EWMA
…